using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Password = Be.Timvw.Framework.Security.TimeOneTimePassword;

namespace Be.Timvw.Framework.Tests.Security.TimeOneTimePassword
{
    /// <summary>
    /// Tests for TimeOneTimePassword
    /// <see cref="http://www.ietf.org/internet-drafts/draft-mraihi-totp-timebased-00.txt/>
    /// </summary>
    [TestClass]
    public class WhenGettingPassword
    {
        private const string Secret = "12345678901234567890";

        private static readonly string[] expectedPasswords = new string[]
        {
            "050471", 
            "005924", 
            "279037"
        };

        private static readonly DateTime[] iterationTimes = new DateTime[]
        {
            DateTime.ParseExact("2005-03-18T01:58:31", "s", null),
            DateTime.ParseExact("2009-02-13T23:31:30", "s", null),
            DateTime.ParseExact("2033-05-18T03:33:20", "s", null)
        };

        private Password TimeOneTimePassword
        {
            get { return new Password(Secret); }
        }

        [TestMethod]
        public void ShouldReturnPasswordsAsInRfc()
        {
            Password timeOneTimePassword = this.TimeOneTimePassword;
            for(int i = 0; i < iterationTimes.Length; ++i)
            {
                DateTime iterationTime = iterationTimes[i];
                string actual = timeOneTimePassword.GetPassword(iterationTime);

                string expected = expectedPasswords[i];

                Assert.AreEqual(expected, actual);
            }
        }

        [TestMethod]
        public void ShouldReturnPasswordForUtcNow()
        {
            Password timeOneTimePassword = this.TimeOneTimePassword;
            string actual = timeOneTimePassword.GetPassword();

            string expected = timeOneTimePassword.GetPassword(DateTime.UtcNow);

            Assert.AreEqual(expected, actual);
        }
    }
}